import { getMessageApi } from '@/hooks/use-message/messageApi';

import axios, { AxiosRequestConfig, AxiosError, AxiosResponse } from 'axios';

import { t } from '@/locales/i18n';
import userStore from '@/store/userStore';

import { Result } from '@/types/api';
import { ResultEnum } from '@/types/enum';

import { resetCookie } from '@/pages/auth/authUtils';

import { debounce } from 'lodash';

const debounceTipShow = debounce((msg: string) => {
  setTimeout(() => {
    const messageApi = getMessageApi();
    if (messageApi) {
      messageApi.info(msg);
    } else {
      console.warn('messageApi 未初始化', msg);
    }
  }, 0);
}, 500);

const debounceErrorShow = debounce((msg: string) => {
  setTimeout(() => {
    const messageApi = getMessageApi();
    if (messageApi) {
      messageApi.error(msg);
    } else {
      console.warn('messageApi 未初始化', msg);
    }
  }, 0);
}, 500);
const axiosInstance = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 50000,
  headers: { 'Content-Type': 'application/json;charset=utf-8' },
  withCredentials: true,
});

// 请求拦截
axiosInstance.interceptors.request.use(
  (config) => {
    config.headers['X-RUIGPT-Source'] = 'share-link';

    // 检测路由中是否有 appId，有则带上
    try {
      const url = new URL(window.location.href);
      const appId = url.searchParams.get('appId') || '';
      if (appId) {
        config.headers['X-App-Id'] = appId;
      }
    } catch (e) {
      console.log('e', e);
    }
    return config;
  },
  (error) => {
    // 请求错误时做些什么
    return Promise.reject(error);
  },
);

// 响应拦截
axiosInstance.interceptors.response.use(
  (res: AxiosResponse<Result>) => {
    if (!res.data) throw new Error(t('sys.api.apiRequestFailed'));

    const { code, data, message } = res.data;
    // 业务请求成功
    const hasSuccess = data;
    if (hasSuccess || code === ResultEnum.SUCCESS || code === ResultEnum.OK) {
      return data;
    }

    console.log('message', message);

    // 业务请求错误
    throw new Error(message || t('sys.api.apiRequestFailed'));
  },
  (error: AxiosError<Result>) => {
    // 检查是否是取消请求的错误
    if (axios.isCancel(error)) {
      console.error('Request canceled');
      return new Promise(() => {});
    }

    const { response, message } = error || {};
    const errMsg =
      (response as AxiosResponse<Result>)?.data?.message || message || t('sys.api.errorMessage');

    const status = (response as AxiosResponse<Result>)?.status;
    console.log('Request error', errMsg, status);
    if (status === ResultEnum.UNAUTHORIZED) {
      const msg401 = (response as AxiosResponse<Result>)?.data?.message || t('sys.api.errMsg401');
      setTimeout(() => {
        // msg401 && Message.info(msg401);
        msg401 && debounceTipShow(msg401);
      }, 0);

      if (msg401 == t('sys.api.errMsgShare')) {
        window.location.href = '/share-link-error';
        return;
      }

      resetCookie();
      userStore.getState().actions.clearUserInfoAndToken();
    } else {
      if (status === ResultEnum.FORBIDDEN) {
        const msg403 = (response as AxiosResponse<Result>)?.data?.message || t('sys.api.errMsg403');
        setTimeout(() => {
          // msg403 && Message.error(msg403);
          msg403 && debounceTipShow(msg403);
        }, 0);
        window.location.href = '/403';
        return;
      } else {
        const msg = (response as AxiosResponse<Result>)?.data?.message;
        setTimeout(() => {
          // msg && Message.error(msg);
          msg && debounceErrorShow(msg);
        }, 0);
      }
    }
    return Promise.reject(error);
  },
);

class APIClient {
  get<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.request({ ...config, method: 'GET' });
  }

  post<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.request({ ...config, method: 'POST' });
  }

  put<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.request({ ...config, method: 'PUT' });
  }

  delete<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.request({ ...config, method: 'DELETE' });
  }

  request<T = any>(config: AxiosRequestConfig): Promise<T> {
    return new Promise((resolve, reject) => {
      axiosInstance
        .request<any, AxiosResponse<Result>>(config)
        .then((res: AxiosResponse<Result>) => {
          resolve(res as unknown as Promise<T>);
        })
        .catch((e: Error | AxiosError) => {
          if (
            axios.isAxiosError(e) &&
            (e?.response?.data?.code == ResultEnum.ERROR ||
              e?.response?.data?.code == ResultEnum.NOT)
          ) {
            reject(e?.response?.data);
          }
          // console.error('e', e?.message);
          reject(e?.message || '请求失败');
        });
    });
  }
}
export default new APIClient();
